
//***************************************************************************
//                      ColDiscreteDynamicsWorld
//***************************************************************************
//  Copyright (C):
//***************************************************************************

#ifndef ColDiscreteDynamicsWorld_H
#define ColDiscreteDynamicsWorld_H
#if defined(__sgi) || defined(_WIN32)
#pragma once
#endif

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <btBulletCollisionCommon.h>
#include <btBulletDynamicsCommon.h>
#include <Collision.h>

namespace col
{

/** 
 */
class ColDiscreteDynamicsWorld : public btDiscreteDynamicsWorld
{
public:
    /** there are 3 more functions than the original version:
     * 1) convert the btRigidBody into the ColObj of CollDet pipeline.
     *      btGImpactMeshShape -> ColGeometry
     *      btMotionState      -> Matrix4
     *
     * 2) create the corresponding btPersistentManifold between the new body
     * and the all existing bodies, which must be organized by btDispatcher so
     * that they are able to be used by dynamics solver.
     *
     * 3) create and the callback function which converts the CollDet
     * collision detection results(overlapped triangles), into the contact
     * data that bullet needs for the dynamics solver, and then register it
     * into the CollDet pipeline.
     * 
     */
    virtual void addCollisionObject( btCollisionObject *colObj,
                                     short int collisionFilterGroup = 0,
                                     short int collisionFilterMask  = 0 );
    //virtual void addRigidBody( btRigidBody* body );

    /** call the CollDet pipeline collision detection check routine and then
     * make note of the results into the corresponding btPersistentManifolds.
     */
    virtual void performDiscreteCollisionDetection();

    /** 1 more function than the original version:
     * It must update the world transformation of all the collision objects in
     * the CollDet pipeline
     * 
     * @param timeStep
     */
    virtual void internalSingleStepSimulation( btScalar timeStep );

private:
    CollisionPipeline *m_pipeline;

    class CreateContactCallback : public Callback
    {
    private:
        btCollisionObject *colObj1;
        btCollisionObject *colObj2;
        btPersistentManifold *manifold;

    public:
        CreateContactCallback( ColID obj1ID,
                               ColID obj2ID,
                               btCollisionObject *colobj1,
                               btCollisionObject *colobj2,
                               btPersistentManifold *manifold,
                               bool always = false,
                               bool all_polygons_in = false,
                               LevelOfDetectionE level_of_detection = LEVEL_EXACT );
                            
        virtual ~CreateContactCallback();

        /** the main function to convert the CollDet check routine result to
         * the data that bullet contact solver needs to simulate the dynamics,
         * should be implemented here
         * 
         * @param data
         */
        virtual void operator () ( const Data *data ) throw ();

    }; // class ContactCallback

}; // class ColDiscreteDynamicsWorld

} // namespace col

#endif // ColDiscreteDynamicsWorld_H

